<?php

namespace App\Traits;

use App\Model\Trade;
use Illuminate\Support\Facades\Redis;

trait TradeQueue
{
    //从买单中获取一条价格最高时间最早的买单交易
    public function getBuy($coinId)
    {
        return $this->get('buy', $coinId);
    }

    //从卖单中获取一条价格最低时间最早的卖单交易
    public function getSell($coinId)
    {
        return $this->get('sell', $coinId);
    }

    //向买单中添加一条记录
    public function addBuy(Trade $trade)
    {
        return $this->add('buy', $trade->coin_id, $trade->id, $trade->price);
    }

    //向卖单中添加一条记录
    public function addSell(Trade $trade)
    {
        return $this->add('sell', $trade->coin_id, $trade->id, $trade->price);
    }

    //从买单记录中移除一条买单
    public function removeBuy($coinId, $tradeId)
    {
        return $this->remove('buy' . $coinId, $tradeId);
    }

    //从卖单记录中移除一条卖单
    public function removeSell($coinId, $tradeId)
    {
        return $this->remove('sell' . $coinId, $tradeId);
    }

    //从买单中获取记录
    protected function get($type, $coinId)
    {
        $key = $type . $coinId;
        //判断队列是否为空
        if (! Redis::zcard($key)) {
            return false;
        }
        $index = $type == 'buy' ? -1 : 0;

        // 最高买价
        $price = array_values(Redis::zrange($key, $index, $index, ['WITHSCORES' => true]))[0];
        // 最高买价所有订单ID
        $ids = Redis::zrangebyscore($key, $price, $price);
        sort($ids);

        $trade = Trade::find($ids[0]);
        if ($trade->status == 1) {
            $this->remove($key, $trade->id);

            return $this->get($type, $coinId);
        }
        if ($trade->number == $trade->deal) {
            $trade->status = 1;
            $trade->save();
            $this->remove($key, $trade->id);

            return $this->get($type, $coinId);
        }

        return $trade;
    }

    //添加买卖单记录
    protected function add($type, $coinId, $tradeId, $tradePrice)
    {
        return Redis::zadd($type . $coinId, [$tradeId => $tradePrice * pow(10, 8)]);
    }

    //移除买卖单记录
    protected function remove($key, $tradeId)
    {
        return Redis::zrem($key, $tradeId);
    }
}